using System;
using System.Collections.Generic;
using System.Text;
using csammisrun.utility;

namespace csammisrun.MsnLib.Utility
{
  public delegate void PayloadReceivedHandler(MsnCommand command);

  public class MsnCommand
  {
    private int _transid = -1;
    private string _command = "";
    private string _original = "";
    private List<string> _parameters = new List<string>();
    private Transaction _trans = null;
    private byte[] _payload = null;

    /// <summary>
    /// Creates a new MSN command from a string received by the server
    /// </summary>
    public MsnCommand(string cmd)
    {
      if (String.IsNullOrEmpty(cmd))
      {
        throw new ArgumentException("Initializing string cannot be null or empty");
      }

      // Trim the CRLF off the end of the command
      if (cmd.EndsWith("\r\n"))
      {
        cmd = cmd.TrimEnd('\r', '\n');
      }

      _original = cmd;
      int paramstart = cmd.IndexOf(' ');
      _command = (paramstart != -1) ? cmd.Substring(0, paramstart) : cmd;
      if (paramstart != -1)
      {
        string args = cmd.Substring(paramstart + 1);
        _parameters = new List<string>(args.Split(' '));
        Int32.TryParse(_parameters[0], out _transid);
        for (int i = 0; i < _parameters.Count; i++ )
        {
          _parameters[i] = HttpUtility.UrlDecode(_parameters[i]);
        }
      }
      else
      {
        _transid = 0;
      }
    }

    public MsnCommand(string cmd, byte[] payload) : this(cmd)
    {
      _payload = payload;
    }
    
    /// <summary>
    /// Gets the alias of the command sent by the server
    /// </summary>
    public string Command
    {
      get { return _command; }
    }

    /// <summary>
    /// Gets a list of parameters sent along with this command
    /// </summary>
    public List<string> Parameters
    {
      get { return _parameters; }
    }

    /// <summary>
    /// Gets or sets the ID of the transaction that triggered this command
    /// </summary>
    /// <remarks>This field is set by the server. <see cref="MsnCommand.Reference"/> is set by a <see cref="CommandProcessor"/>.</remarks>
    public int TransactionID
    {
      get { return _transid; }
    }

    /// <summary>
    /// Gets the payload data received in this command
    /// </summary>
    public byte[] Payload
    {
      get { return _payload; }
    }

    /// <summary>
    /// Gets or sets the <see cref="Transaction"/> that triggered this command
    /// </summary>
    public Transaction Reference
    {
      get { return _trans; }
      set { _trans = value; }
    }

    /// <summary>
    /// Returns the string received by the server that was used to create this MsnCommand
    /// </summary>
    public override string ToString()
    {
      return _original;
    }
  }
}
